//////////////////////////////////////////////
// Vector.js
//
//////////////////////////////////////////////

/// Class ------------------------------------
	
nkMathsTests.Vector = class Vector extends nkDebug.TestClass
{
	// Statics
	static instance = new Vector ("nkMathsTests.algebra") ;

	// Utils
	getVectorConstructor (managed)
	{
		return managed ? nkMaths.Vector : nkMaths.unmanaged.Vector ;
	}

	getQuaternionConstructor (managed)
	{
		return managed ? nkMaths.Quaternion : nkMaths.unmanaged.Quaternion ;
	}

	// Constructors
	testDefaultConstructor (managed)
	{
		const ctor = Vector.instance.getVectorConstructor(managed) ;
		const v = new ctor () ;

		nkDebug.TestUtils.check(nk.isUnmanagedInstance(v) == !managed, "Managed state unexpected") ;
		nkDebug.TestUtils.areNumbersEqual(v._x, 0, 0, "Invalid X") ;
		nkDebug.TestUtils.areNumbersEqual(v._y, 0, 0, "Invalid Y") ;
		nkDebug.TestUtils.areNumbersEqual(v._z, 0, 0, "Invalid Z") ;
		nkDebug.TestUtils.areNumbersEqual(v._w, 0, 0, "Invalid W") ;

		if (!managed)
			v.delete() ;
	}

	testConstructorVec2 (managed)
	{
		const ctor = Vector.instance.getVectorConstructor(managed) ;
		const v = new ctor (1, 2) ;

		nkDebug.TestUtils.check(nk.isUnmanagedInstance(v) == !managed, "Managed state unexpected") ;
		nkDebug.TestUtils.areNumbersEqual(v._x, 1, 0, "Invalid X") ;
		nkDebug.TestUtils.areNumbersEqual(v._y, 2, 0, "Invalid Y") ;
		nkDebug.TestUtils.areNumbersEqual(v._z, 0, 0, "Invalid Z") ;
		nkDebug.TestUtils.areNumbersEqual(v._w, 1, 0, "Invalid W") ;

		if (!managed)
			v.delete() ;
	}

	testConstructorVec3 (managed)
	{
		const ctor = Vector.instance.getVectorConstructor(managed) ;
		const v = new ctor (1, 2, 3) ;

		nkDebug.TestUtils.check(nk.isUnmanagedInstance(v) == !managed, "Managed state unexpected") ;
		nkDebug.TestUtils.areNumbersEqual(v._x, 1, 0, "Invalid X") ;
		nkDebug.TestUtils.areNumbersEqual(v._y, 2, 0, "Invalid Y") ;
		nkDebug.TestUtils.areNumbersEqual(v._z, 3, 0, "Invalid Z") ;
		nkDebug.TestUtils.areNumbersEqual(v._w, 1, 0, "Invalid W") ;

		if (!managed)
			v.delete() ;
	}

	testConstructorVec4 (managed)
	{
		const ctor = Vector.instance.getVectorConstructor(managed) ;
		const v = new ctor (1, 2, 3, 4) ;

		nkDebug.TestUtils.check(nk.isUnmanagedInstance(v) == !managed, "Managed state unexpected") ;
		nkDebug.TestUtils.areNumbersEqual(v._x, 1, 0, "Invalid X") ;
		nkDebug.TestUtils.areNumbersEqual(v._y, 2, 0, "Invalid Y") ;
		nkDebug.TestUtils.areNumbersEqual(v._z, 3, 0, "Invalid Z") ;
		nkDebug.TestUtils.areNumbersEqual(v._w, 4, 0, "Invalid W") ;

		if (!managed)
			v.delete() ;
	}

	testCopyConstructor (managed0, managed1)
	{
		const ctor0 = Vector.instance.getVectorConstructor(managed0) ;
		const ctor1 = Vector.instance.getVectorConstructor(managed1) ;
		const v0 = new ctor0 (1, 2, 3, 4) ;
		const v1 = new ctor1 (v0) ;

		nkDebug.TestUtils.check(nk.isUnmanagedInstance(v0) == !managed0) ;
		nkDebug.TestUtils.check(nk.isUnmanagedInstance(v1) == !managed1) ;
		nkDebug.TestUtils.areNumbersEqual(v1._x, 1, 0, "Invalid X") ;
		nkDebug.TestUtils.areNumbersEqual(v1._y, 2, 0, "Invalid Y") ;
		nkDebug.TestUtils.areNumbersEqual(v1._z, 3, 0, "Invalid Z") ;
		nkDebug.TestUtils.areNumbersEqual(v1._w, 4, 0, "Invalid W") ;

		if (!managed0)
			v0.delete() ;

		if (!managed1)
			v1.delete() ;
	}

	// Length
	testLengthVec2 (managed)
	{
		const ctor = Vector.instance.getVectorConstructor(managed) ;
		const v = new ctor (2, 3) ;
		nkDebug.TestUtils.areNumbersEqual(v.getLengthVec2(), 3.605551275, 0.000001, "Invalid length") ;
		nkDebug.TestUtils.areNumbersEqual(v.getLengthSquaredVec2(), 13, 0, "Invalid squared length") ;

		if (!managed)
			v.delete() ;
	}

	testLengthVec3 (managed)
	{
		const ctor = Vector.instance.getVectorConstructor(managed) ;
		const v = new ctor (2, 3, 4) ;
		nkDebug.TestUtils.areNumbersEqual(v.getLengthVec3(), 5.385164807, 0.000001, "Invalid length") ;
		nkDebug.TestUtils.areNumbersEqual(v.getLengthSquaredVec3(), 29, 0, "Invalid squared length") ;

		if (!managed)
			v.delete() ;
	}

	testLengthVec4 (managed)
	{
		const ctor = Vector.instance.getVectorConstructor(managed) ;
		const v = new ctor (2, 3, 4, 5) ;
		nkDebug.TestUtils.areNumbersEqual(v.getLengthVec4(), 7.348469228, 0.000001, "Invalid length") ;
		nkDebug.TestUtils.areNumbersEqual(v.getLengthSquaredVec4(), 54, 0, "Invalid squared length") ;

		if (!managed)
			v.delete() ;
	}

	// Distance
	testDistanceVec2 (managed0, managed1)
	{
		const ctor0 = Vector.instance.getVectorConstructor(managed0) ;
		const ctor1 = Vector.instance.getVectorConstructor(managed1) ;
		const a = new ctor0 (2, 3) ;
		const b = new ctor1 (-2, -3) ;

		nkDebug.TestUtils.areNumbersEqual(a.getDistanceVec2(b), 7.21110255, 0.000001, "Invalid distance") ;
		nkDebug.TestUtils.areNumbersEqual(a.getDistanceSquaredVec2(b), 52, 0, "Invalid squared distance") ;

		nkDebug.TestUtils.areNumbersEqual(a.getDistanceVec2(b), nkMaths.Vector.distanceVec2(a, b), 0, "Invalid distance static") ;
		nkDebug.TestUtils.areNumbersEqual(a.getDistanceSquaredVec2(b), nkMaths.Vector.distanceSquaredVec2(a, b), 0, "Invalid distance squared static") ;

		if (!managed0)
			a.delete() ;

		if (!managed1)
			b.delete() ;
	}

	testDistanceVec3 (managed0, managed1)
	{
		const ctor0 = Vector.instance.getVectorConstructor(managed0) ;
		const ctor1 = Vector.instance.getVectorConstructor(managed1) ;
		const a = new ctor0 (2, 3, 4) ;
		const b = new ctor1 (-2, -3, -4) ;

		nkDebug.TestUtils.areNumbersEqual(a.getDistanceVec3(b), 10.770329614, 0.000001, "Invalid distance") ;
		nkDebug.TestUtils.areNumbersEqual(a.getDistanceSquaredVec3(b), 116, 0, "Invalid squared distance") ;

		nkDebug.TestUtils.areNumbersEqual(a.getDistanceVec3(b), nkMaths.Vector.distanceVec3(a, b), 0, "Invalid distance static") ;
		nkDebug.TestUtils.areNumbersEqual(a.getDistanceSquaredVec3(b), nkMaths.Vector.distanceSquaredVec3(a, b), 0, "Invalid distance squared static") ;

		if (!managed0)
			a.delete() ;

		if (!managed1)
			b.delete() ;
	}

	testDistanceVec4 (managed0, managed1)
	{
		const ctor0 = Vector.instance.getVectorConstructor(managed0) ;
		const ctor1 = Vector.instance.getVectorConstructor(managed1) ;
		const a = new ctor0 (2, 3, 4, 5) ;
		const b = new ctor1 (-2, -3, -4, -5) ;

		nkDebug.TestUtils.areNumbersEqual(a.getDistanceVec4(b), 14.696938456, 0.000001, "Invalid distance") ;
		nkDebug.TestUtils.areNumbersEqual(a.getDistanceSquaredVec4(b), 216, 0, "Invalid squared distance") ;

		nkDebug.TestUtils.areNumbersEqual(a.getDistanceVec4(b), nkMaths.Vector.distanceVec4(a, b), 0, "Invalid distance static") ;
		nkDebug.TestUtils.areNumbersEqual(a.getDistanceSquaredVec4(b), nkMaths.Vector.distanceSquaredVec4(a, b), 0, "Invalid distance squared static") ;

		if (!managed0)
			a.delete() ;

		if (!managed1)
			b.delete() ;
	}

	// Normalize
	testNormalizeVec2 (managed0, managed1)
	{
		const ctor0 = Vector.instance.getVectorConstructor(managed0) ;
		const ctor1 = Vector.instance.getVectorConstructor(managed1) ;
		const a = new ctor0 (5, 3) ;
		const b = new ctor1 (a.getNormalizedVec2()) ;

		a.normalizeVec2() ;
		nkDebug.TestUtils.areNumbersEqual(a._x, 0.857492983, 0.000001, "Invalid X") ;
		nkDebug.TestUtils.areNumbersEqual(a._y, 0.514495790, 0.000001, "Invalid Y") ;
		nkDebug.TestUtils.areNumbersEqual(a._z, 0, 0, "Invalid Z") ;
		nkDebug.TestUtils.check(a.equals(b)) ;

		if (!managed0)
			a.delete() ;

		if (!managed1)
			b.delete() ;
	}

	testNormalizeVec3 (managed0, managed1)
	{
		const ctor0 = Vector.instance.getVectorConstructor(managed0) ;
		const ctor1 = Vector.instance.getVectorConstructor(managed1) ;
		const a = new ctor0 (5, 3, 8) ;
		const b = new ctor1 (a.getNormalizedVec3()) ;

		a.normalizeVec3() ;
		nkDebug.TestUtils.areNumbersEqual(a._x, 0.505076272, 0.000001, "Invalid X") ;
		nkDebug.TestUtils.areNumbersEqual(a._y, 0.303045763, 0.000001, "Invalid Y") ;
		nkDebug.TestUtils.areNumbersEqual(a._z, 0.808122035, 0.000001, "Invalid Z") ;
		nkDebug.TestUtils.check(a.equals(b)) ;

		if (!managed0)
			a.delete() ;

		if (!managed1)
			b.delete() ;
	}

	testNormalizeVec4 (managed0, managed1)
	{
		const ctor0 = Vector.instance.getVectorConstructor(managed0) ;
		const ctor1 = Vector.instance.getVectorConstructor(managed1) ;
		const a = new ctor0 (5, 3, 8, 10) ;
		const b = new ctor1 (a.getNormalizedVec4()) ;

		a.normalizeVec4() ;
		nkDebug.TestUtils.areNumbersEqual(a._x, 0.355334520, 0.000001, "Invalid X") ;
		nkDebug.TestUtils.areNumbersEqual(a._y, 0.213200718, 0.000001, "Invalid Y") ;
		nkDebug.TestUtils.areNumbersEqual(a._z, 0.568535268, 0.000001, "Invalid Z") ;
		nkDebug.TestUtils.areNumbersEqual(a._w, 0.710669041, 0.000001, "Invalid W") ;
		nkDebug.TestUtils.check(a.equals(b)) ;

		if (!managed0)
			a.delete() ;

		if (!managed1)
			b.delete() ;
	}

	testNormalizeVec2EdgeCase0 (managed)
	{
		const ctor = Vector.instance.getVectorConstructor(managed) ;
		const a = new ctor (0, 0, 0, 0) ;
		const b = new ctor (a.getNormalizedVec2()) ;
		a.normalizeVec2() ;
		nkDebug.TestUtils.areNumbersEqual(a._x, 0, 0, "Wrong edge case X") ;
		nkDebug.TestUtils.areNumbersEqual(a._y, 0, 0, "Wrong edge case Y") ;
		nkDebug.TestUtils.areNumbersEqual(a._z, 0, 0, "Wrong edge case Z") ;
		nkDebug.TestUtils.areNumbersEqual(a._w, 0, 0, "Wrong edge case W") ;

		if (!managed)
		{
			a.delete() ;
			b.delete() ;
		}
	}

	testGetNormalizedVec2DualReturns (managed)
	{
		const ctor = Vector.instance.getVectorConstructor(managed) ;
		const a = new ctor (1, 0, 0) ;

		const m = a.getNormalizedVec2() ;
		nkDebug.TestUtils.check(!nk.isUnmanagedInstance(m), "Unmanaged should be managed") ;

		const u = a.getNormalizedVec2_u() ;
		nkDebug.TestUtils.check(nk.isUnmanagedInstance(u), "Managed should be unmanaged") ;
		u.delete() ;

		if (!managed)
			a.delete() ;
	}

	testNormalizeVec3EdgeCase0 (managed)
	{
		const ctor = Vector.instance.getVectorConstructor(managed) ;
		const a = new ctor (0, 0, 0, 0) ;
		const b = new ctor (a.getNormalizedVec3()) ;
		a.normalizeVec3() ;
		nkDebug.TestUtils.areNumbersEqual(a._x, 0, 0, "Wrong edge case X") ;
		nkDebug.TestUtils.areNumbersEqual(a._y, 0, 0, "Wrong edge case Y") ;
		nkDebug.TestUtils.areNumbersEqual(a._z, 0, 0, "Wrong edge case Z") ;
		nkDebug.TestUtils.areNumbersEqual(a._w, 0, 0, "Wrong edge case W") ;

		if (!managed)
		{
			a.delete() ;
			b.delete() ;
		}
	}

	testGetNormalizedVec3DualReturns (managed)
	{
		const ctor = Vector.instance.getVectorConstructor(managed) ;
		const a = new ctor (1, 0, 0) ;

		const m = a.getNormalizedVec3() ;
		nkDebug.TestUtils.check(!nk.isUnmanagedInstance(m), "Unmanaged should be managed") ;

		const u = a.getNormalizedVec3_u() ;
		nkDebug.TestUtils.check(nk.isUnmanagedInstance(u), "Managed should be unmanaged") ;
		u.delete() ;

		if (!managed)
			a.delete() ;
	}

	testNormalizeVec4EdgeCase0 (managed)
	{
		const ctor = Vector.instance.getVectorConstructor(managed) ;
		const a = new ctor (0, 0, 0, 0) ;
		const b = new ctor (a.getNormalizedVec4()) ;
		a.normalizeVec4() ;
		nkDebug.TestUtils.areNumbersEqual(a._x, 0, 0, "Wrong edge case X vec2") ;
		nkDebug.TestUtils.areNumbersEqual(a._y, 0, 0, "Wrong edge case Y vec2") ;
		nkDebug.TestUtils.areNumbersEqual(a._z, 0, 0, "Wrong edge case Z vec2") ;
		nkDebug.TestUtils.areNumbersEqual(a._w, 0, 0, "Wrong edge case W vec2") ;

		if (!managed)
		{
			a.delete() ;
			b.delete() ;
		}
	}

	testGetNormalizedVec4DualReturns (managed)
	{
		const ctor = Vector.instance.getVectorConstructor(managed) ;
		const a = new ctor (1, 0, 0) ;

		const m = a.getNormalizedVec4() ;
		nkDebug.TestUtils.check(!nk.isUnmanagedInstance(m), "Unmanaged should be managed") ;

		const u = a.getNormalizedVec4_u() ;
		nkDebug.TestUtils.check(nk.isUnmanagedInstance(u), "Managed should be unmanaged") ;
		u.delete() ;

		if (!managed)
			a.delete() ;
	}

	// Dot  product
	testDotProductVec2 (managed0, managed1)
	{
		const ctor0 = Vector.instance.getVectorConstructor(managed0) ;
		const ctor1 = Vector.instance.getVectorConstructor(managed1) ;
		const a = new ctor0 (5, 2) ;
		const b = new ctor1 (14, 30) ;

		nkDebug.TestUtils.areNumbersEqual(a.dotProductVec2(b), 130, 0, "Wrong dot product") ;
		nkDebug.TestUtils.areNumbersEqual(nkMaths.Vector.dotVec2(a, b), 130, 0, "Wrong dot product") ;

		if (!managed0)
			a.delete() ;

		if (!managed1)
			b.delete() ;
	}

	testDotProductVec3 (managed0, managed1)
	{
		const ctor0 = Vector.instance.getVectorConstructor(managed0) ;
		const ctor1 = Vector.instance.getVectorConstructor(managed1) ;
		const a = new ctor0 (5, 2, 6) ;
		const b = new ctor1 (14, 30, 1) ;

		nkDebug.TestUtils.areNumbersEqual(a.dotProductVec3(b), 136, 0, "Wrong dot product") ;
		nkDebug.TestUtils.areNumbersEqual(nkMaths.Vector.dotVec3(a, b), 136, 0, "Wrong dot product") ;

		if (!managed0)
			a.delete() ;

		if (!managed1)
			b.delete() ;
	}

	testDotProductVec4 (managed0, managed1)
	{
		const ctor0 = Vector.instance.getVectorConstructor(managed0) ;
		const ctor1 = Vector.instance.getVectorConstructor(managed1) ;
		const a = new ctor0 (5, 2, 6, 8) ;
		const b = new ctor1 (14, 30, 1, 3) ;

		nkDebug.TestUtils.areNumbersEqual(a.dotProductVec4(b), 160, 0, "Wrong dot product") ;
		nkDebug.TestUtils.areNumbersEqual(nkMaths.Vector.dotVec4(a, b), 160, 0, "Wrong dot product") ;

		if (!managed0)
			a.delete() ;

		if (!managed1)
			b.delete() ;
	}

	// Cross product
	testSetCrossVec3 (managed0, managed1)
	{
		const ctor0 = Vector.instance.getVectorConstructor(managed0) ;
		const ctor1 = Vector.instance.getVectorConstructor(managed1) ;
		const a = new ctor0 (5, 2, 6) ;
		const b = new ctor1 (14, 30, 1) ;

		const r0 = nkMaths.Vector.crossVec3(a, b) ;
		a.setAsCrossVec3(b) ;

		nkDebug.TestUtils.check(r0.equals(a), "Wrong static vs non static result") ;
		nkDebug.TestUtils.areNumbersEqual(r0._x, -178, 0, "Wrong X") ;
		nkDebug.TestUtils.areNumbersEqual(r0._y, 79, 0, "Wrong Y") ;
		nkDebug.TestUtils.areNumbersEqual(r0._z, 122, 0, "Wrong Z") ;
		nkDebug.TestUtils.areNumbersEqual(r0._w, 1, 0, "Wrong W") ;

		if (!managed0)
			a.delete() ;

		if (!managed1)
			b.delete() ;
	}

	testGetCrossVec3 (managed0, managed1)
	{
		const ctor0 = Vector.instance.getVectorConstructor(managed0) ;
		const ctor1 = Vector.instance.getVectorConstructor(managed1) ;
		const a = new ctor0 (5, 2, 6) ;
		const b = new ctor1 (14, 30, 1) ;

		const r0 = a.getCrossVec3(b) ;
		const r1 = nkMaths.Vector.crossVec3(a, b) ;

		nkDebug.TestUtils.check(r0.equals(r1), "Wrong static vs non static result") ;
		nkDebug.TestUtils.areNumbersEqual(r0._x, -178, 0, "Wrong X") ;
		nkDebug.TestUtils.areNumbersEqual(r0._y, 79, 0, "Wrong Y") ;
		nkDebug.TestUtils.areNumbersEqual(r0._z, 122, 0, "Wrong Z") ;
		nkDebug.TestUtils.areNumbersEqual(r0._w, 1, 0, "Wrong W") ;

		if (!managed0)
			a.delete() ;

		if (!managed1)
			b.delete() ;
	}
	
	testGetCrossVec3DualReturns (managed)
	{
		const ctor = Vector.instance.getVectorConstructor(managed) ;
		const a = new ctor (1, 0, 0) ;
		const b = new nkMaths.Vector (1, 1, 1) ;

		const m = a.getCrossVec3(b) ;
		nkDebug.TestUtils.check(!nk.isUnmanagedInstance(m), "Unmanaged should be managed") ;

		const u = a.getCrossVec3_u(b) ;
		nkDebug.TestUtils.check(nk.isUnmanagedInstance(u), "Managed should be unmanaged") ;
		u.delete() ;

		if (!managed)
			a.delete() ;
	}

	// Operators
	testAssignOperator (managed0, managed1)
	{
		const ctor0 = Vector.instance.getVectorConstructor(managed0) ;
		const ctor1 = Vector.instance.getVectorConstructor(managed1) ;
		const a = new ctor0 (5, 2, 6) ;
		const b = new ctor1 (14, 30, 1) ;

		a.assign(b) ;
		nkDebug.TestUtils.check(a.equals(b), "Assignment incorrect copy") ;

		if (!managed0)
			a.delete() ;

		if (!managed1)
			b.delete() ;
	}

	testEqualsOperator (managed0, managed1)
	{
		const ctor0 = Vector.instance.getVectorConstructor(managed0) ;
		const ctor1 = Vector.instance.getVectorConstructor(managed1) ;
		const a = new ctor0 (5, 2, 6) ;
		const b = new ctor1 (14, 30, 1) ;
		const c = new ctor1 (14, 30, 1) ;

		nkDebug.TestUtils.check(a.equals(a), "Assignment incorrect copy") ;
		nkDebug.TestUtils.check(!a.equals(b), "Assignment incorrect copy") ;
		nkDebug.TestUtils.check(!b.equals(a), "Assignment incorrect copy") ;
		nkDebug.TestUtils.check(!a.equals(c), "Assignment incorrect copy") ;
		nkDebug.TestUtils.check(!c.equals(a), "Assignment incorrect copy") ;
		nkDebug.TestUtils.check(b.equals(b), "Assignment incorrect copy") ;
		nkDebug.TestUtils.check(c.equals(b), "Assignment incorrect copy") ;
		nkDebug.TestUtils.check(b.equals(c), "Assignment incorrect copy") ;

		if (!managed0)
			a.delete() ;

		if (!managed1)
		{
			b.delete() ;
			c.delete() ;
		}
	}

	testAddOperator (managed0, managed1)
	{
		const ctor0 = Vector.instance.getVectorConstructor(managed0) ;
		const ctor1 = Vector.instance.getVectorConstructor(managed1) ;
		const a = new ctor0 (5, 2, 6, 9) ;
		const b = new ctor1 (14, 30, 1, 2) ;

		const c = a.add(b) ;
		nkDebug.TestUtils.areNumbersEqual(c._x, a._x + b._x, 0, "Wrong X") ;
		nkDebug.TestUtils.areNumbersEqual(c._y, a._y + b._y, 0, "Wrong Y") ;
		nkDebug.TestUtils.areNumbersEqual(c._z, a._z + b._z, 0, "Wrong Z") ;
		nkDebug.TestUtils.areNumbersEqual(c._w, a._w + b._w, 0, "Wrong W") ;

		if (!managed0)
			a.delete() ;

		if (!managed1)
			b.delete() ;
	}

	testAddDualReturns (managed)
	{
		const ctor = Vector.instance.getVectorConstructor(managed) ;
		const a = new ctor () ;
		const b = new nkMaths.Vector () ;

		const m = a.add(b) ;
		nkDebug.TestUtils.check(!nk.isUnmanagedInstance(m), "Unmanaged should be managed") ;

		const u = a.add_u(b) ;
		nkDebug.TestUtils.check(nk.isUnmanagedInstance(u), "Managed should be unmanaged") ;
		u.delete() ;

		if (!managed)
			a.delete() ;
	}

	testAddScalarOperator (managed)
	{
		const ctor = Vector.instance.getVectorConstructor(managed) ;
		const a = new ctor (5, 2, 6, 9) ;
		const b = 7 ;

		const c = a.addScalar(b) ;
		nkDebug.TestUtils.areNumbersEqual(c._x, a._x + b, 0, "Wrong X") ;
		nkDebug.TestUtils.areNumbersEqual(c._y, a._y + b, 0, "Wrong Y") ;
		nkDebug.TestUtils.areNumbersEqual(c._z, a._z + b, 0, "Wrong Z") ;
		nkDebug.TestUtils.areNumbersEqual(c._w, a._w + b, 0, "Wrong W") ;

		if (!managed)
			a.delete() ;
	}

	testAddScalarDualReturns (managed)
	{
		const ctor = Vector.instance.getVectorConstructor(managed) ;
		const a = new ctor () ;

		const m = a.addScalar(1) ;
		nkDebug.TestUtils.check(!nk.isUnmanagedInstance(m), "Unmanaged should be managed") ;

		const u = a.addScalar_u(1) ;
		nkDebug.TestUtils.check(nk.isUnmanagedInstance(u), "Managed should be unmanaged") ;
		u.delete() ;

		if (!managed)
			a.delete() ;
	}

	testSubOperator (managed0, managed1)
	{
		const ctor0 = Vector.instance.getVectorConstructor(managed0) ;
		const ctor1 = Vector.instance.getVectorConstructor(managed1) ;
		const a = new ctor0 (5, 2, 6, 9) ;
		const b = new ctor1 (14, 30, 1, 2) ;

		const c = a.sub(b) ;
		nkDebug.TestUtils.areNumbersEqual(c._x, a._x - b._x, 0, "Wrong X") ;
		nkDebug.TestUtils.areNumbersEqual(c._y, a._y - b._y, 0, "Wrong Y") ;
		nkDebug.TestUtils.areNumbersEqual(c._z, a._z - b._z, 0, "Wrong Z") ;
		nkDebug.TestUtils.areNumbersEqual(c._w, a._w - b._w, 0, "Wrong W") ;

		if (!managed0)
			a.delete() ;

		if (!managed1)
			b.delete() ;
	}

	testSubDualReturns (managed)
	{
		const ctor = Vector.instance.getVectorConstructor(managed) ;
		const a = new ctor () ;
		const b = new nkMaths.Vector () ;

		const m = a.sub(b) ;
		nkDebug.TestUtils.check(!nk.isUnmanagedInstance(m), "Unmanaged should be managed") ;

		const u = a.sub_u(b) ;
		nkDebug.TestUtils.check(nk.isUnmanagedInstance(u), "Managed should be unmanaged") ;
		u.delete() ;

		if (!managed)
			a.delete() ;
	}

	testSubScalarOperator (managed)
	{
		const ctor = Vector.instance.getVectorConstructor(managed) ;
		const a = new ctor (5, 2, 6, 9) ;
		const b = 7 ;

		const c = a.subScalar(b) ;
		nkDebug.TestUtils.areNumbersEqual(c._x, a._x - b, 0, "Wrong X") ;
		nkDebug.TestUtils.areNumbersEqual(c._y, a._y - b, 0, "Wrong Y") ;
		nkDebug.TestUtils.areNumbersEqual(c._z, a._z - b, 0, "Wrong Z") ;
		nkDebug.TestUtils.areNumbersEqual(c._w, a._w - b, 0, "Wrong W") ;

		if (!managed)
			a.delete() ;
	}

	testSubScalarDualReturns (managed)
	{
		const ctor = Vector.instance.getVectorConstructor(managed) ;
		const a = new ctor () ;

		const m = a.subScalar(1) ;
		nkDebug.TestUtils.check(!nk.isUnmanagedInstance(m), "Unmanaged should be managed") ;

		const u = a.subScalar_u(1) ;
		nkDebug.TestUtils.check(nk.isUnmanagedInstance(u), "Managed should be unmanaged") ;
		u.delete() ;

		if (!managed)
			a.delete() ;
	}

	testMulOperator (managed0, managed1)
	{
		const ctor0 = Vector.instance.getVectorConstructor(managed0) ;
		const ctor1 = Vector.instance.getVectorConstructor(managed1) ;
		const a = new ctor0 (5, 2, 6, 9) ;
		const b = new ctor1 (14, 30, 1, 2) ;

		const c = a.mul(b) ;
		nkDebug.TestUtils.areNumbersEqual(c._x, a._x * b._x, 0, "Wrong X") ;
		nkDebug.TestUtils.areNumbersEqual(c._y, a._y * b._y, 0, "Wrong Y") ;
		nkDebug.TestUtils.areNumbersEqual(c._z, a._z * b._z, 0, "Wrong Z") ;
		nkDebug.TestUtils.areNumbersEqual(c._w, a._w * b._w, 0, "Wrong W") ;

		if (!managed0)
			a.delete() ;

		if (!managed1)
			b.delete() ;
	}

	testMulDualReturns (managed)
	{
		const ctor = Vector.instance.getVectorConstructor(managed) ;
		const a = new ctor () ;
		const b = new nkMaths.Vector (1, 1, 1, 1) ;

		const m = a.mul(b) ;
		nkDebug.TestUtils.check(!nk.isUnmanagedInstance(m), "Unmanaged should be managed") ;

		const u = a.mul_u(b) ;
		nkDebug.TestUtils.check(nk.isUnmanagedInstance(u), "Managed should be unmanaged") ;
		u.delete() ;

		if (!managed)
			a.delete() ;
	}

	testMulScalarOperator (managed)
	{
		const ctor = Vector.instance.getVectorConstructor(managed) ;
		const a = new ctor (5, 2, 6, 9) ;
		const b = 7 ;

		const c = a.mulScalar(b) ;
		nkDebug.TestUtils.areNumbersEqual(c._x, a._x * b, 0, "Wrong X") ;
		nkDebug.TestUtils.areNumbersEqual(c._y, a._y * b, 0, "Wrong Y") ;
		nkDebug.TestUtils.areNumbersEqual(c._z, a._z * b, 0, "Wrong Z") ;
		nkDebug.TestUtils.areNumbersEqual(c._w, a._w * b, 0, "Wrong W") ;

		if (!managed)
			a.delete() ;
	}

	testMulScalarDualReturns (managed)
	{
		const ctor = Vector.instance.getVectorConstructor(managed) ;
		const a = new ctor () ;

		const m = a.mulScalar(1) ;
		nkDebug.TestUtils.check(!nk.isUnmanagedInstance(m), "Unmanaged should be managed") ;

		const u = a.mulScalar_u(1) ;
		nkDebug.TestUtils.check(nk.isUnmanagedInstance(u), "Managed should be unmanaged") ;
		u.delete() ;

		if (!managed)
			a.delete() ;
	}

	testMulQuaternionOperator (managedV, managedQ)
	{
		const ctorQ = Vector.instance.getQuaternionConstructor(managedQ) ;
		const ctorV = Vector.instance.getVectorConstructor(managedV) ;

		const q = new ctorQ (0.7071068, 0, 0, 0.7071068) ;
		const x = new ctorV (1, 0, 0) ;
		const y = new ctorV (0, 1, 0) ;
		const z = new ctorV (0, 0, 1) ;

		const checkVector = function (a, b)
		{
			nkDebug.TestUtils.areNumbersEqual(a._x, b._x, 0.0001, "Bad X") ;
			nkDebug.TestUtils.areNumbersEqual(a._y, b._y, 0.0001, "Bad Y") ;
			nkDebug.TestUtils.areNumbersEqual(a._z, b._z, 0.0001, "Bad Z") ;
			nkDebug.TestUtils.areNumbersEqual(a._w, b._w, 0.0001, "Bad W") ;
		} ;

		checkVector(x.mulQuaternion(q), x) ;
		checkVector(y.mulQuaternion(q), z) ;
		checkVector(z.mulQuaternion(q), new nkMaths.Vector (0, -1, 0)) ;

		if (!managedQ)
			q.delete() ;

		if (!managedV)
		{
			x.delete() ;
			y.delete() ;
			z.delete() ;
		}
	}

	testMulQuaternionDualReturns (managed)
	{
		const ctor = Vector.instance.getVectorConstructor(managed) ;
		const a = new ctor () ;
		const q = new nkMaths.Quaternion () ;

		const m = a.mulQuaternion(q) ;
		nkDebug.TestUtils.check(!nk.isUnmanagedInstance(m), "Unmanaged should be managed") ;

		const u = a.mulQuaternion_u(q) ;
		nkDebug.TestUtils.check(nk.isUnmanagedInstance(u), "Managed should be unmanaged") ;
		u.delete() ;

		if (!managed)
			a.delete() ;
	}

	testDivOperator (managed0, managed1)
	{
		const ctor0 = Vector.instance.getVectorConstructor(managed0) ;
		const ctor1 = Vector.instance.getVectorConstructor(managed1) ;
		const a = new ctor0 (5, 2, 6, 9) ;
		const b = new ctor1 (14, 30, 1, 2) ;

		const c = a.div(b) ;
		nkDebug.TestUtils.areNumbersEqual(c._x, a._x / b._x, 0.000001, "Wrong X") ;
		nkDebug.TestUtils.areNumbersEqual(c._y, a._y / b._y, 0.000001, "Wrong Y") ;
		nkDebug.TestUtils.areNumbersEqual(c._z, a._z / b._z, 0.000001, "Wrong Z") ;
		nkDebug.TestUtils.areNumbersEqual(c._w, a._w / b._w, 0.000001, "Wrong W") ;

		if (!managed0)
			a.delete() ;

		if (!managed1)
			b.delete() ;
	}

	testDivDualReturns (managed)
	{
		const ctor = Vector.instance.getVectorConstructor(managed) ;
		const a = new ctor () ;
		const b = new nkMaths.Vector (1, 1, 1, 1) ;

		const m = a.div(b) ;
		nkDebug.TestUtils.check(!nk.isUnmanagedInstance(m), "Unmanaged should be managed") ;

		const u = a.div_u(b) ;
		nkDebug.TestUtils.check(nk.isUnmanagedInstance(u), "Managed should be unmanaged") ;
		u.delete() ;

		if (!managed)
			a.delete() ;
	}

	testDivScalarOperator (managed)
	{
		const ctor = Vector.instance.getVectorConstructor(managed) ;
		const a = new ctor (5, 2, 6, 9) ;
		const b = 7 ;

		const c = a.divScalar(b) ;
		nkDebug.TestUtils.areNumbersEqual(c._x, a._x / b, 0.000001, "Wrong X") ;
		nkDebug.TestUtils.areNumbersEqual(c._y, a._y / b, 0.000001, "Wrong Y") ;
		nkDebug.TestUtils.areNumbersEqual(c._z, a._z / b, 0.000001, "Wrong Z") ;
		nkDebug.TestUtils.areNumbersEqual(c._w, a._w / b, 0.000001, "Wrong W") ;

		if (!managed)
			a.delete() ;
	}

	testDivScalarDualReturns (managed)
	{
		const ctor = Vector.instance.getVectorConstructor(managed) ;
		const a = new ctor () ;

		const m = a.divScalar(1) ;
		nkDebug.TestUtils.check(!nk.isUnmanagedInstance(m), "Unmanaged should be managed") ;

		const u = a.divScalar_u(1) ;
		nkDebug.TestUtils.check(nk.isUnmanagedInstance(u), "Managed should be unmanaged") ;
		u.delete() ;

		if (!managed)
			a.delete() ;
	}

	testInfOperator (managed0, managed1)
	{
		const ctor0 = Vector.instance.getVectorConstructor(managed0) ;
		const ctor1 = Vector.instance.getVectorConstructor(managed1) ;
		const a = new ctor0 (1, 1, 1, 1) ;
		const b = new ctor1 (0.2, 2, 3, 0.6) ;

		nkDebug.TestUtils.check(a.inf(b), "Wrong comparison result") ;
		nkDebug.TestUtils.check(!a.inf(a), "Wrong comparison result self") ;

		if (!managed0)
			a.delete() ;

		if (!managed1)
			b.delete() ;
	}

	testInfOrEqualOperator (managed0, managed1)
	{
		const ctor0 = Vector.instance.getVectorConstructor(managed0) ;
		const ctor1 = Vector.instance.getVectorConstructor(managed1) ;
		const a = new ctor0 (1, 1, 1, 1) ;
		const b = new ctor1 (0.2, 2, 3, 0.6) ;

		nkDebug.TestUtils.check(a.infOrEqual(b), "Wrong comparison result") ;
		nkDebug.TestUtils.check(a.infOrEqual(a), "Wrong comparison result self") ;

		if (!managed0)
			a.delete() ;

		if (!managed1)
			b.delete() ;
	}

	testGreaterOperator (managed0, managed1)
	{
		const ctor0 = Vector.instance.getVectorConstructor(managed0) ;
		const ctor1 = Vector.instance.getVectorConstructor(managed1) ;
		const a = new ctor0 (0.2, 2, 3, 0.6) ;
		const b = new ctor1 (1, 1, 1, 1) ;

		nkDebug.TestUtils.check(a.greater(b), "Wrong comparison result") ;
		nkDebug.TestUtils.check(!a.greater(a), "Wrong comparison result self") ;

		if (!managed0)
			a.delete() ;

		if (!managed1)
			b.delete() ;
	}

	testGreaterOrEqualOperator (managed0, managed1)
	{
		const ctor0 = Vector.instance.getVectorConstructor(managed0) ;
		const ctor1 = Vector.instance.getVectorConstructor(managed1) ;
		const a = new ctor0 (0.2, 2, 3, 0.6) ;
		const b = new ctor1 (1, 1, 1, 1) ;

		nkDebug.TestUtils.check(a.greaterOrEqual(b), "Wrong comparison result") ;
		nkDebug.TestUtils.check(a.greaterOrEqual(a), "Wrong comparison result self") ;

		if (!managed0)
			a.delete() ;

		if (!managed1)
			b.delete() ;
	}

	nkTests =
	{
		// Constructors
		DefaultConstructorUnmanaged : function ()
		{
			Vector.instance.testDefaultConstructor(false) ;
		},
		DefaultConstructorManaged : function ()
		{
			Vector.instance.testDefaultConstructor(true) ;
		},
		ConstructorVec2Unmanaged : function ()
		{
			Vector.instance.testConstructorVec2(false) ;
		},
		ConstructorVec2Managed : function ()
		{
			Vector.instance.testConstructorVec2(true) ;
		},
		ConstructorVec3Unmanaged : function ()
		{
			Vector.instance.testConstructorVec3(false) ;
		},
		ConstructorVec3Managed : function ()
		{
			Vector.instance.testConstructorVec3(true) ;
		},
		ConstructorVec4Unmanaged : function ()
		{
			Vector.instance.testConstructorVec4(false) ;
		},
		ConstructorVec4Managed : function ()
		{
			Vector.instance.testConstructorVec4(true) ;
		},
		CopyConstructorUnmanagedToUnmanaged : function ()
		{
			Vector.instance.testCopyConstructor(false, false) ;
		},
		CopyConstructorUnmanagedToManaged : function ()
		{
			Vector.instance.testCopyConstructor(false, true) ;
		},
		CopyConstructorManagedToUnmanaged : function ()
		{
			Vector.instance.testCopyConstructor(true, false) ;
		},
		CopyConstructorManagedToManaged : function ()
		{
			Vector.instance.testCopyConstructor(true, true) ;
		},

		// Length
		LengthVec2Unmanaged : function ()
		{
			Vector.instance.testLengthVec2(false) ;
		},
		LengthVec2Managed : function ()
		{
			Vector.instance.testLengthVec2(true) ;
		},
		LengthVec3Unmanaged : function ()
		{
			Vector.instance.testLengthVec3(false) ;
		},
		LengthVec3Managed : function ()
		{
			Vector.instance.testLengthVec3(true) ;
		},
		LengthVec4Unmanaged : function ()
		{
			Vector.instance.testLengthVec4(false) ;
		},
		LengthVec4Managed : function ()
		{
			Vector.instance.testLengthVec4(true) ;
		},

		// Distance
		DistanceVec2Unmanaged : function ()
		{
			Vector.instance.testDistanceVec2(false, false) ;
		},
		DistanceVec2UnmanagedManaged : function ()
		{
			Vector.instance.testDistanceVec2(false, true) ;
		},
		DistanceVec2ManagedUnmanaged : function ()
		{
			Vector.instance.testDistanceVec2(true, false) ;
		},
		DistanceVec2Managed : function ()
		{
			Vector.instance.testDistanceVec2(true, true) ;
		},
		DistanceVec3Unmanaged : function ()
		{
			Vector.instance.testDistanceVec3(false, false) ;
		},
		DistanceVec3UnmanagedManaged : function ()
		{
			Vector.instance.testDistanceVec3(false, true) ;
		},
		DistanceVec3ManagedUnmanaged : function ()
		{
			Vector.instance.testDistanceVec3(true, false) ;
		},
		DistanceVec3Managed : function ()
		{
			Vector.instance.testDistanceVec3(true, true) ;
		},
		DistanceVec4Unmanaged : function ()
		{
			Vector.instance.testDistanceVec4(false, false) ;
		},
		DistanceVec4UnmanagedManaged : function ()
		{
			Vector.instance.testDistanceVec4(false, true) ;
		},
		DistanceVec4ManagedUnmanaged : function ()
		{
			Vector.instance.testDistanceVec4(true, false) ;
		},
		DistanceVec4Managed : function ()
		{
			Vector.instance.testDistanceVec4(true, true) ;
		},

		// Normalize
		NormalizeVec2Unmanaged : function ()
		{
			Vector.instance.testNormalizeVec2(false, false) ;
		},
		NormalizeVec2Managed : function ()
		{
			Vector.instance.testNormalizeVec2(true, true) ;
		},
		NormalizeVec3Unmanaged : function ()
		{
			Vector.instance.testNormalizeVec3(false, false) ;
		},
		NormalizeVec3Managed : function ()
		{
			Vector.instance.testNormalizeVec3(true, true) ;
		},
		NormalizeVec4Unmanaged : function ()
		{
			Vector.instance.testNormalizeVec4(false, false) ;
		},
		NormalizeVec4Managed : function ()
		{
			Vector.instance.testNormalizeVec4(true, true) ;
		},
		NormalizeVec2EdgeCase0Unmanaged : function ()
		{
			Vector.instance.testNormalizeVec2EdgeCase0(false) ;
		},
		NormalizeVec2EdgeCase0Managed : function ()
		{
			Vector.instance.testNormalizeVec2EdgeCase0(true) ;
		},
		NormalizeVec3EdgeCase0Unmanaged : function ()
		{
			Vector.instance.testNormalizeVec3EdgeCase0(false) ;
		},
		NormalizeVec3EdgeCase0Managed : function ()
		{
			Vector.instance.testNormalizeVec3EdgeCase0(true) ;
		},
		NormalizeVec4EdgeCase0Unmanaged : function ()
		{
			Vector.instance.testNormalizeVec4EdgeCase0(false) ;
		},
		NormalizeVec4EdgeCase0Managed : function ()
		{
			Vector.instance.testNormalizeVec4EdgeCase0(true) ;
		},
		GetNormalizedVec2DualReturnsUnmanaged : function ()
		{
			Vector.instance.testGetNormalizedVec2DualReturns(false) ;
		},
		GetNormalizedVec2DualReturnsManaged : function ()
		{
			Vector.instance.testGetNormalizedVec2DualReturns(true) ;
		},
		GetNormalizedVec3DualReturnsUnmanaged : function ()
		{
			Vector.instance.testGetNormalizedVec3DualReturns(false) ;
		},
		GetNormalizedVec3DualReturnsManaged : function ()
		{
			Vector.instance.testGetNormalizedVec3DualReturns(true) ;
		},
		GetNormalizedVec4DualReturnsUnmanaged : function ()
		{
			Vector.instance.testGetNormalizedVec4DualReturns(false) ;
		},
		GetNormalizedVec4DualReturnsManaged : function ()
		{
			Vector.instance.testGetNormalizedVec4DualReturns(true) ;
		},

		// Dot product
		DotProductVec2Unmanaged : function ()
		{
			Vector.instance.testDotProductVec2(false, false) ;
		},
		DotProductVec2UnmanagedManaged : function ()
		{
			Vector.instance.testDotProductVec2(false, true) ;
		},
		DotProductVec2ManagedUnmanaged : function ()
		{
			Vector.instance.testDotProductVec2(true, false) ;
		},
		DotProductVec2Managed : function ()
		{
			Vector.instance.testDotProductVec2(true, true) ;
		},
		DotProductVec3Unmanaged : function ()
		{
			Vector.instance.testDotProductVec3(false, false) ;
		},
		DotProductVec3UnmanagedManaged : function ()
		{
			Vector.instance.testDotProductVec3(false, true) ;
		},
		DotProductVec3ManagedUnmanaged : function ()
		{
			Vector.instance.testDotProductVec3(true, false) ;
		},
		DotProductVec3Managed : function ()
		{
			Vector.instance.testDotProductVec3(true, true) ;
		},
		DotProductVec4Unmanaged : function ()
		{
			Vector.instance.testDotProductVec4(false, false) ;
		},
		DotProductVec4UnmanagedManaged : function ()
		{
			Vector.instance.testDotProductVec4(false, true) ;
		},
		DotProductVec4ManagedUnmanaged : function ()
		{
			Vector.instance.testDotProductVec4(true, false) ;
		},
		DotProductVec4Managed : function ()
		{
			Vector.instance.testDotProductVec4(true, true) ;
		},

		// Cross product
		SetCrossProductVec3Unmanaged : function ()
		{
			Vector.instance.testSetCrossVec3(false, false) ;
		},
		SetCrossProductVec3UnmanagedManaged : function ()
		{
			Vector.instance.testSetCrossVec3(false, true) ;
		},
		SetCrossProductVec3ManagedUnmanaged : function ()
		{
			Vector.instance.testSetCrossVec3(true, false) ;
		},
		SetCrossProductVec3Managed : function ()
		{
			Vector.instance.testSetCrossVec3(true, true) ;
		},
		GetCrossProductVec3Unmanaged : function ()
		{
			Vector.instance.testGetCrossVec3(false, false) ;
		},
		GetCrossProductVec3UnmanagedManaged : function ()
		{
			Vector.instance.testGetCrossVec3(false, true) ;
		},
		GetCrossProductVec3ManagedUnmanaged : function ()
		{
			Vector.instance.testGetCrossVec3(true, false) ;
		},
		GetCrossProductVec3Managed : function ()
		{
			Vector.instance.testGetCrossVec3(true, true) ;
		},
		GetCrossVec3DualReturnsUnmanaged : function ()
		{
			Vector.instance.testGetCrossVec3DualReturns(false) ;
		},
		GetCrossVec3DualReturnsManaged : function ()
		{
			Vector.instance.testGetCrossVec3DualReturns(true) ;
		},

		// Operators
		AssignOperatorUnmanaged : function ()
		{
			Vector.instance.testAssignOperator(false, false) ;
		},
		AssignOperatorUnmanagedManaged : function ()
		{
			Vector.instance.testAssignOperator(false, true) ;
		},
		AssignOperatorManagedUnmanaged : function ()
		{
			Vector.instance.testAssignOperator(true, false) ;
		},
		AssignOperatorManaged : function ()
		{
			Vector.instance.testAssignOperator(true, true) ;
		},
		EqualsOperatorUnmanaged : function ()
		{
			Vector.instance.testEqualsOperator(false, false) ;
		},
		EqualsOperatorUnmanagedManaged : function ()
		{
			Vector.instance.testEqualsOperator(false, true) ;
		},
		EqualsOperatorManagedUnmanaged : function ()
		{
			Vector.instance.testEqualsOperator(true, false) ;
		},
		EqualsOperatorManaged : function ()
		{
			Vector.instance.testEqualsOperator(true, true) ;
		},
		AddOperatorUnmanaged : function ()
		{
			Vector.instance.testAddOperator(false, false) ;
		},
		AddOperatorUnmanagedManaged : function ()
		{
			Vector.instance.testAddOperator(false, true) ;
		},
		AddOperatorManagedUnmanaged : function ()
		{
			Vector.instance.testAddOperator(true, false) ;
		},
		AddOperatorManaged : function ()
		{
			Vector.instance.testAddOperator(true, true) ;
		},
		AddDualReturnsUnmanaged : function ()
		{
			Vector.instance.testAddDualReturns(false) ;
		},
		AddDualReturnsManaged : function ()
		{
			Vector.instance.testAddDualReturns(true) ;
		},
		AddScalarOperatorUnmanaged : function ()
		{
			Vector.instance.testAddScalarOperator(false, false) ;
		},
		AddScalarOperatorUnmanagedManaged : function ()
		{
			Vector.instance.testAddScalarOperator(false, true) ;
		},
		AddScalarOperatorManagedUnmanaged : function ()
		{
			Vector.instance.testAddScalarOperator(true, false) ;
		},
		AddScalarOperatorManaged : function ()
		{
			Vector.instance.testAddScalarOperator(true, true) ;
		},
		AddScalarDualReturnsUnmanaged : function ()
		{
			Vector.instance.testAddScalarDualReturns(false) ;
		},
		AddScalarDualReturnsManaged : function ()
		{
			Vector.instance.testAddScalarDualReturns(true) ;
		},
		SubOperatorUnmanaged : function ()
		{
			Vector.instance.testSubOperator(false, false) ;
		},
		SubOperatorUnmanagedManaged : function ()
		{
			Vector.instance.testSubOperator(false, true) ;
		},
		SubOperatorManagedUnmanaged : function ()
		{
			Vector.instance.testSubOperator(true, false) ;
		},
		SubOperatorManaged : function ()
		{
			Vector.instance.testSubOperator(true, true) ;
		},
		SubDualReturnsUnmanaged : function ()
		{
			Vector.instance.testSubDualReturns(false) ;
		},
		SubDualReturnsManaged : function ()
		{
			Vector.instance.testSubDualReturns(true) ;
		},
		SubScalarOperatorUnmanaged : function ()
		{
			Vector.instance.testSubScalarOperator(false, false) ;
		},
		SubScalarOperatorUnmanagedManaged : function ()
		{
			Vector.instance.testSubScalarOperator(false, true) ;
		},
		SubScalarOperatorManagedUnmanaged : function ()
		{
			Vector.instance.testSubScalarOperator(true, false) ;
		},
		SubScalarOperatorManaged : function ()
		{
			Vector.instance.testSubScalarOperator(true, true) ;
		},
		SubScalarDualReturnsUnmanaged : function ()
		{
			Vector.instance.testSubScalarDualReturns(false) ;
		},
		SubScalarDualReturnsManaged : function ()
		{
			Vector.instance.testSubScalarDualReturns(true) ;
		},
		MulOperatorUnmanaged : function ()
		{
			Vector.instance.testMulOperator(false, false) ;
		},
		MulOperatorUnmanagedManaged : function ()
		{
			Vector.instance.testMulOperator(false, true) ;
		},
		MulOperatorManagedUnmanaged : function ()
		{
			Vector.instance.testMulOperator(true, false) ;
		},
		MulOperatorManaged : function ()
		{
			Vector.instance.testMulOperator(true, true) ;
		},
		MulDualReturnsUnmanaged : function ()
		{
			Vector.instance.testMulDualReturns(false) ;
		},
		MulDualReturnsManaged : function ()
		{
			Vector.instance.testMulDualReturns(true) ;
		},
		MulScalarOperatorUnmanaged : function ()
		{
			Vector.instance.testMulScalarOperator(false, false) ;
		},
		MulScalarOperatorUnmanagedManaged : function ()
		{
			Vector.instance.testMulScalarOperator(false, true) ;
		},
		MulScalarOperatorManagedUnmanaged : function ()
		{
			Vector.instance.testMulScalarOperator(true, false) ;
		},
		MulScalarOperatorManaged : function ()
		{
			Vector.instance.testMulScalarOperator(true, true) ;
		},
		MulScalarDualReturnsUnmanaged : function ()
		{
			Vector.instance.testMulScalarDualReturns(false) ;
		},
		MulScalarDualReturnsManaged : function ()
		{
			Vector.instance.testMulScalarDualReturns(true) ;
		},
		MulQuaternionOperatorUnmanaged : function ()
		{
			Vector.instance.testMulQuaternionOperator(false, false) ;
		},
		MulQuaternionOperatorUnmanagedManaged : function ()
		{
			Vector.instance.testMulQuaternionOperator(false, true) ;
		},
		MulQuaternionOperatorManagedUnmanaged : function ()
		{
			Vector.instance.testMulQuaternionOperator(true, false) ;
		},
		MulQuaternionOperatorManaged : function ()
		{
			Vector.instance.testMulQuaternionOperator(true, true) ;
		},
		MulQuaternionDualReturnsUnmanaged : function ()
		{
			Vector.instance.testMulQuaternionDualReturns(false) ;
		},
		MulQuaternionDualReturnsManaged : function ()
		{
			Vector.instance.testMulQuaternionDualReturns(true) ;
		},
		DivOperatorUnmanaged : function ()
		{
			Vector.instance.testDivOperator(false, false) ;
		},
		DivOperatorUnmanagedManaged : function ()
		{
			Vector.instance.testDivOperator(false, true) ;
		},
		DivOperatorManagedUnmanaged : function ()
		{
			Vector.instance.testDivOperator(true, false) ;
		},
		DivOperatorManaged : function ()
		{
			Vector.instance.testDivOperator(true, true) ;
		},
		DivDualReturnsUnmanaged : function ()
		{
			Vector.instance.testDivDualReturns(false) ;
		},
		DivDualReturnsManaged : function ()
		{
			Vector.instance.testDivDualReturns(true) ;
		},
		DivScalarOperatorUnmanaged : function ()
		{
			Vector.instance.testDivScalarOperator(false, false) ;
		},
		DivScalarOperatorUnmanagedManaged : function ()
		{
			Vector.instance.testDivScalarOperator(false, true) ;
		},
		DivScalarOperatorManagedUnmanaged : function ()
		{
			Vector.instance.testDivScalarOperator(true, false) ;
		},
		DivScalarOperatorManaged : function ()
		{
			Vector.instance.testDivScalarOperator(true, true) ;
		},
		DivScalarDualReturnsUnmanaged : function ()
		{
			Vector.instance.testDivScalarDualReturns(false) ;
		},
		DivScalarDualReturnsManaged : function ()
		{
			Vector.instance.testDivScalarDualReturns(true) ;
		},
		InfOperatorUnmanaged : function ()
		{
			Vector.instance.testInfOperator(false, false) ;
		},
		InfOperatorUnmanagedManaged : function ()
		{
			Vector.instance.testInfOperator(false, true) ;
		},
		InfOperatorManagedUnmanaged : function ()
		{
			Vector.instance.testInfOperator(true, false) ;
		},
		InfOperatorManaged : function ()
		{
			Vector.instance.testInfOperator(true, true) ;
		},
		InfOrEqualOperatorUnmanaged : function ()
		{
			Vector.instance.testInfOrEqualOperator(false, false) ;
		},
		InfOrEqualOperatorUnmanagedManaged : function ()
		{
			Vector.instance.testInfOrEqualOperator(false, true) ;
		},
		InfOrEqualOperatorManagedUnmanaged : function ()
		{
			Vector.instance.testInfOrEqualOperator(true, false) ;
		},
		InfOrEqualOperatorManaged : function ()
		{
			Vector.instance.testInfOrEqualOperator(true, true) ;
		},
		GreaterOperatorUnmanaged : function ()
		{
			Vector.instance.testGreaterOperator(false, false) ;
		},
		GreaterOperatorUnmanagedManaged : function ()
		{
			Vector.instance.testGreaterOperator(false, true) ;
		},
		GreaterOperatorManagedUnmanaged : function ()
		{
			Vector.instance.testGreaterOperator(true, false) ;
		},
		GreaterOperatorManaged : function ()
		{
			Vector.instance.testGreaterOperator(true, true) ;
		},
		GreaterOrEqualOperatorUnmanaged : function ()
		{
			Vector.instance.testGreaterOrEqualOperator(false, false) ;
		},
		GreaterOrEqualOperatorUnmanagedManaged : function ()
		{
			Vector.instance.testGreaterOrEqualOperator(false, true) ;
		},
		GreaterOrEqualOperatorManagedUnmanaged : function ()
		{
			Vector.instance.testGreaterOrEqualOperator(true, false) ;
		},
		GreaterOrEqualOperatorManaged : function ()
		{
			Vector.instance.testGreaterOrEqualOperator(true, true) ;
		}
	}
}